package com.net.oil.gaode;

import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.SparseArray;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.amap.api.location.AMapLocation;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.navi.AMapNavi;
import com.amap.api.navi.AMapNaviListener;
import com.amap.api.navi.model.AMapLaneInfo;
import com.amap.api.navi.model.AMapModelCross;
import com.amap.api.navi.model.AMapNaviCameraInfo;
import com.amap.api.navi.model.AMapNaviCross;
import com.amap.api.navi.model.AMapNaviInfo;
import com.amap.api.navi.model.AMapNaviLocation;
import com.amap.api.navi.model.AMapNaviPath;
import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo;
import com.amap.api.navi.model.AMapServiceAreaInfo;
import com.amap.api.navi.model.AimLessModeCongestionInfo;
import com.amap.api.navi.model.AimLessModeStat;
import com.amap.api.navi.model.NaviInfo;
import com.amap.api.navi.model.NaviLatLng;
import com.amap.api.navi.view.RouteOverLay;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.route.BusRouteResult;
import com.amap.api.services.route.DriveRouteResult;
import com.amap.api.services.route.RideRouteResult;
import com.amap.api.services.route.RouteSearch;
import com.amap.api.services.route.WalkRouteResult;
import com.autonavi.tbt.TrafficFacilityInfo;
import com.net.oil.R;
import com.net.oil.app.Constant;
import com.net.oil.gaode.adpater.BusRoutRecyclerViewAdapter;
import com.net.oil.gaode.adpater.RoutRecyclerViewAdapter;
import com.net.oil.util.DisplayUtil;
import com.net.oil.util.SharedPreferencesKey;
import com.net.oil.util.SharedPreferencesUtil;
import com.net.oil.util.StringUtil;
import com.net.oil.widget.ToastUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;

/**
 * 路径规划
 * 读该类，先参考高德导航路径规划demo
 */
public class RoutePlanActivity extends AppCompatActivity implements AMapNaviListener, AMap.OnMyLocationChangeListener {


    @BindView(R.id.map_view)
    MapView mapView;
    @BindView(R.id.drive_button)
    RadioButton driveButton;
    @BindView(R.id.bus_button)
    RadioButton busButton;
    @BindView(R.id.walk_button)
    RadioButton walkButton;
    @BindView(R.id.radio_group)
    RadioGroup radioGroup;
    @BindView(R.id.route_recycler_view)
    RecyclerView routeRecyclerView;
    @BindView(R.id.start_navi)
    TextView startNavi;
    @BindView(R.id.bus_path_recycler_view)
    RecyclerView busPathRecyclerView;

    /**
     * 导航对象(单例)
     */
    private AMapNavi mAMapNavi;
    private AMap aMap;
    private MyLocationStyle myLocationStyle;

    private Marker mStartMarker;
    private Marker mEndMarker;
    private NaviLatLng endLatlng;
    private List<NaviLatLng> startList = new ArrayList<NaviLatLng>();

    private RouteSearch mRouteSearch;

    /**
     * 途径点坐标集合
     */
    private List<NaviLatLng> wayList = new ArrayList<NaviLatLng>();
    /**
     * 终点坐标集合［建议就一个终点］
     */
    private List<NaviLatLng> endList = new ArrayList<NaviLatLng>();
    /**
     * 保存当前算好的路线
     */
    private SparseArray<RouteOverLay> routeOverlays = new SparseArray<RouteOverLay>();

    /**
     * 当前用户选中的路线，在下个页面进行导航
     */
    private int routeIndex;
    /**
     * 路线的权值，重合路线情况下，权值高的路线会覆盖权值低的路线
     **/
    private int zindex = 1;
    /**
     * 路线计算成功标志位
     */
    private boolean calculateSuccess = false;
    private boolean chooseRouteSuccess = false;

    private AMapLocation aMapLocation;

    private RoutRecyclerViewAdapter recyclerViewAdapter;

    private List<AMapNaviPath> pathList;        //recyclerView数据源

    private Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_route_plan);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
            Window window = getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(getResources().getColor(R.color.blue));
        }
        ButterKnife.bind(this);
        context = this.getApplicationContext();
        //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState)，创建地图
        mapView.onCreate(savedInstanceState);
        initDate();
        initView();
    }

    private void initDate() {
        double lng = getIntent().getDoubleExtra(Constant.INTENT_LNG, 0.00);
        double lat = getIntent().getDoubleExtra(Constant.INTENT_LAT, 0.00);
        endLatlng = new NaviLatLng(lat, lng);
    }

    private void initView() {
        initMapView();

        startNavi.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent gpsintent = new Intent(getApplicationContext(), RouteNaviActivity.class);
                gpsintent.putExtra("gps", true);
                startActivity(gpsintent);
            }
        });

        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                if (checkedId == R.id.drive_button) {
                    startRoutePlan(RoutePlanType.DRIVE);
                    if (busPathRecyclerView.getVisibility() == View.VISIBLE) {
                        busPathRecyclerView.setVisibility(View.GONE);
                    }
                } else if (checkedId == R.id.bus_button) {
                    startRoutePlan(RoutePlanType.BUS);
                } else if (checkedId == R.id.walk_button) {
                    startRoutePlan(RoutePlanType.WALK);
                    if (busPathRecyclerView.getVisibility() == View.VISIBLE) {
                        busPathRecyclerView.setVisibility(View.GONE);
                    }
                }
            }
        });
    }

    /**
     * 初始化地图相关配置
     */
    private void initMapView() {
        aMap = mapView.getMap();//得到aMap对象
        LatLng latLng = new LatLng(34.7522485720, 113.6665463448);       //构造默认位置
        aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 11));
        // 如果要设置定位的默认状态，可以在此处进行设置
        myLocationStyle = new MyLocationStyle();
        aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
        aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        aMap.setMyLocationStyle(myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE));
        aMap.setOnMyLocationChangeListener(this);

        // 初始化Marker添加到地图
//        mStartMarker = aMap.addMarker(new MarkerOptions().icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.start))));
//        mEndMarker = aMap.addMarker(new MarkerOptions().icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.end))));

        mAMapNavi = AMapNavi.getInstance(getApplicationContext());
        mAMapNavi.addAMapNaviListener(this);

        //公交路径规划，初始化，参考地图公交路径规划demo
        mRouteSearch = new RouteSearch(this);
        mRouteSearch.setRouteSearchListener(routeSearchListener);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        startList.clear();
        wayList.clear();
        endList.clear();
        routeOverlays.clear();
        //在activity执行onDestroy时执行mMapView.onDestroy()，销毁地图
        mapView.onDestroy();

        /*
         * 当前页面只是展示地图，activity销毁后不需要再回调导航的状态
         */
        mAMapNavi.removeAMapNaviListener(this);
        mAMapNavi.destroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView.onResume ()，重新绘制加载地图
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView.onPause ()，暂停地图的绘制
        mapView.onPause();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState)，保存地图当前的状态
        mapView.onSaveInstanceState(outState);
    }

    /**
     * 定位成回调
     *
     * @param location Android 定位信息
     */
    @Override
    public void onMyLocationChange(Location location) {

        //如果当前位置信息为空，则获取最后一次定位信息
        aMapLocation = LocationHandle.getInstance().getCurrentLocation();      //获取高德定位当前位置信息
        if (aMapLocation == null) {
            aMapLocation = LocationHandle.getInstance().getLastLocation();      //获取高德定位最后一次定为信息，可能不是最新的
        }
        if (aMapLocation != null) {
//            mStartMarker.setPosition(new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude()));
            aMap.addMarker(new MarkerOptions().position(new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude())).icon(BitmapDescriptorFactory.fromResource(R.drawable.start)));
            startList.add(new NaviLatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude()));
//            mEndMarker.setPosition(new LatLng(endLatlng.getLatitude(), endLatlng.getLongitude()));
            aMap.addMarker(new MarkerOptions().position(new LatLng(endLatlng.getLatitude(), endLatlng.getLongitude())).icon(BitmapDescriptorFactory.fromResource(R.drawable.end)));
            endList.add(new NaviLatLng(endLatlng.getLatitude(), endLatlng.getLongitude()));
            startRoutePlan(RoutePlanType.DRIVE);
        } else {
            ToastUtil.showErrorToast(this, "定位失败");
        }
    }

    /**
     * 清除当前地图上算好的路线
     */
    private void clearRoute() {
        for (int i = 0; i < routeOverlays.size(); i++) {
            RouteOverLay routeOverlay = routeOverlays.valueAt(i);
            routeOverlay.removeFromMap();
        }
        routeOverlays.clear();
    }

    /**
     * 开始算路
     *
     * @param planType 算路类型RoutePlanType
     */
    private void startRoutePlan(RoutePlanType planType) {
        switch (planType) {
            case DRIVE:
                clearRoute();
                /*
                 * strategyFlag转换出来的值都对应PathPlanningStrategy常量，用户也可以直接传入PathPlanningStrategy常量进行算路。
                 * 如:mAMapNavi.calculateDriveRoute(mStartList, mEndList, mWayPointList,PathPlanningStrategy.DRIVING_DEFAULT);
                */
                int strategyFlag = 0;
                try {
                    strategyFlag = mAMapNavi.strategyConvert(true, false, false, true, true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (strategyFlag >= 0) {
                    mAMapNavi.calculateDriveRoute(startList, endList, wayList, strategyFlag);
                }
                break;
            case BUS:
                final RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(
                        new LatLonPoint(startList.get(0).getLatitude(), startList.get(0).getLongitude()),
                        new LatLonPoint(endList.get(0).getLatitude(), endList.get(0).getLongitude()));
                // 公交路径规划
                if (!StringUtil.isEmpty(aMapLocation.getCityCode())) {
                    // 第一个参数表示路径规划的起点和终点，第二个参数表示公交查询模式，第三个参数表示公交查询城市区号，第四个参数表示是否计算夜班车，0表示不计算
                    RouteSearch.BusRouteQuery query = new RouteSearch.BusRouteQuery(fromAndTo, RouteSearch.BUS_DEFAULT,
                            aMapLocation.getCityCode(), 0);
                    mRouteSearch.calculateBusRouteAsyn(query);// 异步路径规划公交模式查询
                } else {
                    String cityCode = SharedPreferencesUtil.getStringParam(context, SharedPreferencesKey.CITY_CODE, "");
                    RouteSearch.BusRouteQuery query = new RouteSearch.BusRouteQuery(fromAndTo, RouteSearch.BUS_DEFAULT,
                            cityCode, 0);
                    mRouteSearch.calculateBusRouteAsyn(query);
                }


                break;
            case WALK:
                clearRoute();
                mAMapNavi.calculateWalkRoute(startList.get(0), endList.get(0));
                break;
        }

    }

    /**
     * 选择路径
     */
    public void changeRoute() {
        if (!calculateSuccess) {
            Toast.makeText(this, "请先算路", Toast.LENGTH_SHORT).show();
            return;
        }
        /**
         * 计算出来的路径只有一条
         */
        if (routeOverlays.size() == 1) {
            chooseRouteSuccess = true;
            //必须告诉AMapNavi 你最后选择的哪条路
            mAMapNavi.selectRouteId(routeOverlays.keyAt(0));
            return;
        }

        if (routeIndex >= routeOverlays.size())
            routeIndex = 0;
        int routeID = routeOverlays.keyAt(routeIndex);
        //突出选择的那条路
        for (int i = 0; i < routeOverlays.size(); i++) {
            int key = routeOverlays.keyAt(i);
            routeOverlays.get(key).setTransparency(0.4f);
        }
        routeOverlays.get(routeID).setTransparency(1);
        /**把用户选择的那条路的权值弄高，使路线高亮显示的同时，重合路段不会变的透明**/
        routeOverlays.get(routeID).setZindex(zindex++);

        //必须告诉AMapNavi 你最后选择的哪条路
        mAMapNavi.selectRouteId(routeID);

        chooseRouteSuccess = true;

    }

    @Override
    public void onCalculateRouteSuccess(int[] ints) {
        //清空上次计算的路径列表。
        routeOverlays.clear();
        if (ints.length > 1) {
            HashMap<Integer, AMapNaviPath> paths = mAMapNavi.getNaviPaths();

            pathList = new ArrayList<>();    //更新数据
            for (int i = 0; i < ints.length; i++) {
                AMapNaviPath path = paths.get(ints[i]);
                if (path != null) {
                    drawRoutes(ints[i], path);
                }
                pathList.add(path);
                updateRecyclerView(pathList);
            }
        } else {
            AMapNaviPath path = mAMapNavi.getNaviPath();
            pathList = new ArrayList<>();    //更新数据
            if (path != null) {
                drawRoutes(0, path);
            }
            pathList.add(path);
            updateRecyclerView(pathList);
        }

    }

    private void drawRoutes(int routeId, AMapNaviPath path) {
        calculateSuccess = true;
        aMap.moveCamera(CameraUpdateFactory.changeTilt(0));
        RouteOverLay routeOverLay = new RouteOverLay(aMap, path, this);
        routeOverLay.setTrafficLine(false);
        routeOverLay.addToMap();
        routeOverlays.put(routeId, routeOverLay);

        zoomToSpan();       //缩放地图

        routeIndex = 0;
        changeRoute();
    }

    /**
     * recycleView数据
     *
     * @param pathList 路径
     */
    private void updateRecyclerView(List<AMapNaviPath> pathList) {
        GridLayoutManager manager = new GridLayoutManager(this, pathList.size() > 3 ? 3 : pathList.size());
        recyclerViewAdapter = new RoutRecyclerViewAdapter(this);
        routeRecyclerView.setLayoutManager(manager);
        routeRecyclerView.setAdapter(recyclerViewAdapter);

        recyclerViewAdapter.setOnItemClickListener(new RoutRecyclerViewAdapter.OnItemClickListener() {
            @Override
            public void onClick(int position) {
                routeIndex = position;
                changeRoute();
            }
        });

        recyclerViewAdapter.updateData(pathList);
    }


    /**
     * 公交路径规划搜索
     */
    private RouteSearch.OnRouteSearchListener routeSearchListener = new RouteSearch.OnRouteSearchListener() {
        @Override
        public void onBusRouteSearched(BusRouteResult result, int errorCode) {
            aMap.clear();// 清理地图上的所有覆盖物
            if (errorCode == AMapException.CODE_AMAP_SUCCESS) {
                if (result != null && result.getPaths() != null) {
                    if (result.getPaths().size() > 0) {
                        //显示公交搜索信息
                        BusRoutRecyclerViewAdapter busRoutRecyclerViewAdapter = new BusRoutRecyclerViewAdapter(context, result);
                        LinearLayoutManager manager = new LinearLayoutManager(context);
                        busPathRecyclerView.setLayoutManager(manager);
                        busPathRecyclerView.setAdapter(busRoutRecyclerViewAdapter);
                        if (busPathRecyclerView.getVisibility() == View.GONE) {
                            busPathRecyclerView.setVisibility(View.VISIBLE);
                        }
                    } else if (result.getPaths() == null) {
                        ToastUtil.showErrorToast(context, "没有搜索到结果");
                    }
                } else {
                    ToastUtil.showErrorToast(context, "没有搜索到结果");
                }
            } else {
                ToastUtil.showErrorToast(context, "没有搜索到结果");
            }
        }

        @Override
        public void onDriveRouteSearched(DriveRouteResult driveRouteResult, int i) {

        }

        @Override
        public void onWalkRouteSearched(WalkRouteResult walkRouteResult, int i) {

        }

        @Override
        public void onRideRouteSearched(RideRouteResult rideRouteResult, int i) {

        }
    };

    @Override
    public void onInitNaviFailure() {

    }

    @Override
    public void onInitNaviSuccess() {

    }

    @Override
    public void onStartNavi(int i) {

    }

    @Override
    public void onTrafficStatusUpdate() {

    }

    @Override
    public void onLocationChange(AMapNaviLocation aMapNaviLocation) {

    }

    @Override
    public void onGetNavigationText(int i, String s) {

    }

    @Override
    public void onGetNavigationText(String s) {

    }

    @Override
    public void onEndEmulatorNavi() {

    }

    @Override
    public void onArriveDestination() {

    }

    @Override
    public void onCalculateRouteFailure(int i) {
        calculateSuccess = false;
    }

    @Override
    public void onReCalculateRouteForYaw() {

    }

    @Override
    public void onReCalculateRouteForTrafficJam() {

    }

    @Override
    public void onArrivedWayPoint(int i) {

    }

    @Override
    public void onGpsOpenStatus(boolean b) {

    }

    @Override
    public void onNaviInfoUpdate(NaviInfo naviInfo) {

    }

    @Override
    public void onNaviInfoUpdated(AMapNaviInfo aMapNaviInfo) {

    }

    @Override
    public void updateCameraInfo(AMapNaviCameraInfo[] aMapNaviCameraInfos) {

    }

    @Override
    public void updateIntervalCameraInfo(AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo aMapNaviCameraInfo1, int i) {

    }

    @Override
    public void onServiceAreaUpdate(AMapServiceAreaInfo[] aMapServiceAreaInfos) {

    }

    @Override
    public void showCross(AMapNaviCross aMapNaviCross) {

    }

    @Override
    public void hideCross() {

    }

    @Override
    public void showModeCross(AMapModelCross aMapModelCross) {

    }

    @Override
    public void hideModeCross() {

    }

    @Override
    public void showLaneInfo(AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1) {

    }

    @Override
    public void showLaneInfo(AMapLaneInfo aMapLaneInfo) {

    }

    @Override
    public void hideLaneInfo() {

    }

    @Override
    public void notifyParallelRoad(int i) {

    }

    @Override
    public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) {

    }

    @Override
    public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) {

    }

    @Override
    public void OnUpdateTrafficFacility(TrafficFacilityInfo trafficFacilityInfo) {

    }

    @Override
    public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {

    }

    @Override
    public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) {

    }

    @Override
    public void onPlayRing(int i) {

    }

    /**
     * 调整地图大小
     */
    public void zoomToSpan() {
        try {
            LatLngBounds bounds = getLatLngBounds();
            aMap.animateCamera(CameraUpdateFactory
                    .newLatLngBounds(bounds, DisplayUtil.dip2px(100)));
        } catch (Throwable e) {
            e.printStackTrace();
        }

    }

    protected LatLngBounds getLatLngBounds() {
        LatLngBounds.Builder b = LatLngBounds.builder();
        b.include(new LatLng(startList.get(0).getLatitude(), startList.get(0).getLongitude()));
        b.include(new LatLng(endList.get(0).getLatitude(), endList.get(0).getLongitude()));
        return b.build();
    }

    public enum RoutePlanType {
        DRIVE,      //驾车路径规划
        BUS,        //公交路径规划
        WALK        //步行路径规划
    }
}
